package ecom.dao;

/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
import ecom.entity.Category;
import ecom.exception.DataAccessLayerException;
import ecom.entity.Product;
import java.util.List;
import org.hibernate.Criteria;
import org.hibernate.FetchMode;
import org.hibernate.HibernateException;
import org.hibernate.Session;
import org.hibernate.Transaction;
import org.hibernate.criterion.Expression;
import org.hibernate.criterion.Restrictions;

/**
 *
 * @author simonrichard
 */
public class ProductDAO extends AbstractDAO {

    public static String NAME = "name";
    public static String CATEGORY = "category";
    public static String STORE_ID = "store_id";
    public static String Product_ID = "idProduct";


    public ProductDAO() {
        super();
    }

    /**
     * Crée un Product dans la base de données
     * @param product Product à créer
     */
    public void create(Product product) throws DataAccessLayerException {
        super.saveOrUpdate(product);
    }

    /**
     * Supprime un Product de la base de données
     * @param product Product à supprimer
     */
    public void delete(Product product) throws DataAccessLayerException {
        super.delete(product);
    }

    /**
     * Recherche un Product en fonction de sa clé primaire
     * @param id id du Product
     * @return Product Retourne un Product
     */
    public Product find(Integer id) throws DataAccessLayerException {
        return (Product) super.find(Product.class, id);
    }

    /**
     * Met à jour un Product dans la base de données
     * @param product Product à mettre à jour
     */
    public void update(Product product) throws DataAccessLayerException {
        super.saveOrUpdate(product);
    }

    /**
     * Retourne tous les Product de la base de données
     * @return List<Product> Retourne une liste de Product
     */
    public List<Product> findAll() throws DataAccessLayerException {
        return super.findAll(Product.class);
    }

    /**
     * Recherche un Product en fonction de snom
     * @param name nom du Product
     * @return Product Retourne un Product
     */
    public Product findByName(String name) throws DataAccessLayerException {
        Product product = null;
        try {
            startOperation();
            Criteria crit = session.createCriteria(Product.class);
            crit.add(Expression.eq(NAME, name));
            product = (Product) crit.uniqueResult();
            tx.commit();
        } catch (HibernateException e) {
            handleException(e);
        }
        return product;
    }

    /**
     * Recherche les Product en fonction d'un groupe de mot contenu dans son nom
     * @param inName mot contenu dans le nom
     * @return List<Product> Retourne une liste de Product
     */
    public List<Product> findByInName(String inName) throws DataAccessLayerException{
        List<Product> products = null;
        inName = "%" + inName + "%";
        try {
            startOperation();
            Criteria crit = session.createCriteria(Product.class).add(Restrictions.like("name", inName));
            products = crit.list();
            tx.commit();
        } catch (HibernateException e) {
            handleException(e);
        }
        return products;
    }

    /**
     * Recherche les Product en fonction de sa catégorie
     * @param id id catégorie du Product
     * @return List<Product> Retourne une liste de Product
     */
    public List<Product> findAllByCategory(int idCategory) throws DataAccessLayerException{
        List<Product> products = null;
        try {
            startOperation();
            Criteria crit = session.createCriteria(Product.class);
            crit.add(Expression.eq("category", new Category(idCategory)));
            products = crit.list();
            tx.commit();
        } catch (HibernateException e) {
            handleException(e);
        }
        return products;
    }
    
    /**
     * Recherche les Product en fonction de son store
     * @param id id store du Product
     * @return List<Product> Retourne une liste de Product
     */
    public List<Product> findAllByStore(int idStore) throws DataAccessLayerException{
        List<Product> products = null;
        try {
            startOperation();
            Criteria crit = session.createCriteria(Product.class);
            crit.add(Expression.eq(STORE_ID, idStore));
            products = crit.list();
            tx.commit();
        } catch (HibernateException e) {
            handleException(e);
        }
        return products;
    }

    /**
     * Recherche un Product en fonction de son id
     * @param idProduct id du Product
     * @return Product Retourne un Product
     */
    public Product findById(int idProduct) throws DataAccessLayerException{
        Product product = null;
        try {
            startOperation();
            Criteria crit = session.createCriteria(Product.class);
            crit.add(Expression.eq(Product_ID, idProduct));
            product = (Product) crit.uniqueResult();
            tx.commit();
        } catch (HibernateException e) {
            handleException(e);
        }
        return product;

    }
    
    /**
     * Recherche un Product en fonction du prix
     * @param price prix maximum
     * @return List<Product> Retourne une liste de Product
     */
    public List<Product> findByPriceUnder(double price) throws DataAccessLayerException{
        List<Product> products = null;
        try {
            startOperation();
            Criteria crit = session.createCriteria(Product.class)
                    .setFetchMode("product_store",FetchMode.JOIN).add(Restrictions.le("product_store.price", price));
            products = crit.list();
            tx.commit();
        } catch (HibernateException e) {
            handleException(e);
        }
        return products;

    }

    

//    public static void main(String[] args) {
//
//        ProductDAO dao = new ProductDAO();
//
//        System.out.println("test");
//        List<Product> results  = dao.findByPriceUnder(40);
//
//        for(Product p : results) {
//            System.out.println(p);
//            
//        }
//
//        dao.closeSession();
//    }
}
